using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using WIT.DAQ.Core.Extension;
using WIT.DAQ.Core.Protocols.Socket;

namespace WIT.DAQ.Core.Forms;

/// <summary>
/// Socket发送消息
/// </summary>
internal class SocketServerMonitorForm : BaseForm
{
	/// <summary>
	/// SocketServer监控的数据类型
	/// </summary>
	internal enum MsgType
	{
		/// <summary>
		/// 发送
		/// </summary>
		Send,
		/// <summary>
		/// 接收
		/// </summary>
		Receive
	}

	/// <summary>
	/// 标识是否正在循环发送数据
	/// </summary>
	private bool IsLoopSending = false;

	/// <summary>
	/// 异步向客户端发送数据
	/// </summary>
	private BackgroundWorker BW_SENDDATA;

	/// <summary>
	/// Required designer variable.
	/// </summary>
	private IContainer components = null;

	private GroupBox groupBox1;

	private TextBox txtMsg;

	private CheckBox cbMonitorSingleClient;

	private RadioButton rdShowEncoding;

	private RadioButton rdShowHex;

	private GroupBox groupBox2;

	private NumericUpDown nudInterval;

	private Label label4;

	private CheckBox cbLoop;

	private RadioButton rdSendEncoding;

	private RadioButton rdSendHex;

	private Button btnSend;

	private TextBox txtSendData;

	private Label label1;

	private ComboBox cmbClients;

	private ContextMenuStrip contextMenuStrip;

	private ToolStripMenuItem tsmiClearMsg;

	private CheckBox cbSendSingleClient;

	/// <summary>
	///
	/// </summary>
	internal SocketServerMonitorForm(IEnumerable<TCPClient> clients)
	{
		InitializeComponent();
		ComboBox.ObjectCollection items = cmbClients.Items;
		object[] items2 = clients.ToArray();
		items.AddRange(items2);
		cmbClients.DisplayMember = "Name";
	}

	private void SocketServerMonitorForm_Load(object sender, EventArgs e)
	{
		base.Disposed += SocketServerMonitorForm_Disposed;
		if (BW_SENDDATA == null)
		{
			BW_SENDDATA = new BackgroundWorker
			{
				WorkerSupportsCancellation = true
			};
			BW_SENDDATA.DoWork += BW_SENDDATA_DoWork;
			BW_SENDDATA.RunWorkerCompleted += BW_SENDDATA_RunWorkerCompleted;
		}
	}

	/// <summary>
	/// 增加一个SocketClient
	/// </summary>
	/// <param name="client"></param>
	internal void AddClient(TCPClient client)
	{
		cmbClients.Items.Add(client);
	}

	/// <summary>
	/// 插入一个SocketClient
	/// </summary>
	/// <param name="index"></param>
	/// <param name="client"></param>
	internal void InsertClient(int index, TCPClient client)
	{
		List<TCPClient> list = (List<TCPClient>)cmbClients.DataSource;
		list.Insert(index, client);
	}

	/// <summary>
	/// 移除一个SocketClient
	/// </summary>
	/// <param name="client"></param>
	internal void RemoveClient(TCPClient client)
	{
		foreach (TCPClient item in cmbClients.Items)
		{
			if (item == client)
			{
				cmbClients.Items.Remove(client);
				break;
			}
		}
	}

	/// <summary>
	/// 清除所有SocketClient
	/// </summary>
	internal void ClearClients()
	{
		cmbClients.Items.Clear();
	}

	/// <summary>
	/// 发送数据
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void btnSend_Click(object sender, EventArgs e)
	{
		if (IsLoopSending)
		{
			BW_SENDDATA.CancelAsync();
		}
		else if (!string.IsNullOrEmpty(txtSendData.Text.Trim()))
		{
			if (cbSendSingleClient.Checked && cmbClients.SelectedItem == null)
			{
				MessageBox.Show("请在列表中选择一个客户端");
				return;
			}
			if (!cbLoop.Checked)
			{
				try
				{
					byte[] data = null;
					if (rdSendEncoding.Checked)
					{
						data = Encoding.UTF8.GetBytes(txtSendData.Text.Trim());
					}
					else if (rdSendHex.Checked)
					{
						data = (from t in txtSendData.Text.Trim().Split(' ')
							select Convert.ToByte(t, 16)).ToArray();
					}
					SendData(data);
					return;
				}
				catch (Exception ex)
				{
					MessageBox.Show(ex.Message);
					return;
				}
			}
			BW_SENDDATA.RunWorkerAsync();
			btnSend.Text = "停止发送(&C)";
			txtSendData.Enabled = false;
			cbLoop.Enabled = false;
			nudInterval.Enabled = false;
			cbSendSingleClient.Enabled = false;
			rdSendEncoding.Enabled = false;
			rdSendHex.Enabled = false;
			IsLoopSending = true;
		}
		else
		{
			MessageBox.Show("请输入需要发送的内容");
		}
	}

	private void BW_SENDDATA_DoWork(object sender, DoWorkEventArgs e)
	{
		BackgroundWorker bw = sender as BackgroundWorker;
		try
		{
			byte[] bytes = null;
			Invoke((Action)delegate
			{
				try
				{
					if (rdSendEncoding.Checked)
					{
						bytes = Encoding.UTF8.GetBytes(txtSendData.Text.Trim());
					}
					else if (rdSendHex.Checked)
					{
						bytes = (from t in txtSendData.Text.Trim().Split(' ')
							select Convert.ToByte(t, 16)).ToArray();
					}
				}
				catch (Exception ex3)
				{
					if (!bw.CancellationPending)
					{
						bw.CancelAsync();
						MessageBox.Show(ex3.Message);
					}
				}
			});
			int millisecondsTimeout = Convert.ToInt32(nudInterval.Value);
			while (!bw.CancellationPending)
			{
				Invoke((Action)delegate
				{
					try
					{
						SendData(bytes);
					}
					catch (Exception ex2)
					{
						if (!bw.CancellationPending)
						{
							bw.CancelAsync();
							MessageBox.Show(ex2.Message);
						}
					}
				});
				Thread.Sleep(millisecondsTimeout);
			}
		}
		catch (Exception ex)
		{
			if (!bw.CancellationPending)
			{
				MessageBox.Show(ex.Message);
			}
		}
	}

	private void BW_SENDDATA_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
	{
		btnSend.Text = "循环发送(&S)";
		txtSendData.Enabled = true;
		cbLoop.Enabled = true;
		nudInterval.Enabled = true;
		cbSendSingleClient.Enabled = true;
		rdSendEncoding.Enabled = true;
		rdSendHex.Enabled = true;
		IsLoopSending = false;
	}

	/// <summary>
	/// 向客户端发送数据
	/// </summary>
	/// <param name="data">要发送的数据</param>
	private void SendData(byte[] data)
	{
		if (cbSendSingleClient.Checked)
		{
			if (cmbClients.SelectedItem != null)
			{
				TCPClient tCPClient = (TCPClient)cmbClients.SelectedItem;
				int num = tCPClient.NetWork.Client.Send(data);
				if (num == data.Length)
				{
					WriteMsg(tCPClient, data, MsgType.Send);
				}
				else
				{
					WriteErrMsg(tCPClient, $"发送失败：需要发送的字节数为{data.Length}，实际发送的字节数为{num}", MsgType.Send);
				}
			}
			return;
		}
		foreach (TCPClient item in cmbClients.Items)
		{
			int num2 = item.NetWork.Client.Send(data);
			if (num2 == data.Length)
			{
				WriteMsg(item, data, MsgType.Send);
			}
			else
			{
				WriteErrMsg(item, $"发送失败：需要发送的字节数为{data.Length}，实际发送的字节数为{num2}", MsgType.Send);
			}
		}
	}

	/// <summary>
	/// 切换单次/循环发送
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void cbLoop_CheckedChanged(object sender, EventArgs e)
	{
		if (cbLoop.Checked)
		{
			btnSend.Text = "循环发送(&S)";
		}
		else
		{
			btnSend.Text = "发送(&S)";
		}
	}

	/// <summary>
	/// 切换发送数据的码制（Encoding）
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void rdSendEncoding_CheckedChanged(object sender, EventArgs e)
	{
		if (string.IsNullOrEmpty(txtSendData.Text.Trim()))
		{
			return;
		}
		try
		{
			if (rdSendEncoding.Checked)
			{
				string text = string.Empty;
				string text2 = txtSendData.Text.Trim();
				string[] array = text2.Split(' ');
				string[] array2 = array;
				foreach (string value in array2)
				{
					int utf = Convert.ToInt32(value, 16);
					text += char.ConvertFromUtf32(utf);
				}
				txtSendData.Text = text;
			}
		}
		catch (Exception ex)
		{
			MessageBox.Show(ex.Message);
		}
	}

	/// <summary>
	/// 切换发送数据的码制（Hex）
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void rdSendHex_CheckedChanged(object sender, EventArgs e)
	{
		if (!string.IsNullOrEmpty(txtSendData.Text.Trim()) && rdSendHex.Checked)
		{
			string empty = string.Empty;
			string s = txtSendData.Text.Trim();
			byte[] bytes = Encoding.UTF8.GetBytes(s);
			txtSendData.Text = bytes.ToHexStr();
		}
	}

	/// <summary>
	/// 显示监控消息（收/发）
	/// </summary>
	/// <param name="client"></param>
	/// <param name="data">消息内容</param>
	/// <param name="msgType">收/发</param>
	internal void WriteMsg(TCPClient client, byte[] data, MsgType msgType)
	{
		bool flag = false;
		if (cbMonitorSingleClient.Checked)
		{
			if (cmbClients.SelectedItem != null && (TCPClient)cmbClients.SelectedItem == client)
			{
				flag = true;
			}
		}
		else
		{
			flag = true;
		}
		if (!flag)
		{
			return;
		}
		string text = string.Empty;
		if (rdShowEncoding.Checked)
		{
			text = Encoding.UTF8.GetString(data);
		}
		else if (rdShowHex.Checked)
		{
			text = string.Join(" ", data.Select((byte t) => $"{t:X2}"));
		}
		txtMsg.AppendText("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "]（" + ((msgType == MsgType.Send) ? "发" : "收") + "）" + client.Name + " => " + text + "\r\n");
	}

	/// <summary>
	/// 显示错误信息（收/发）
	/// </summary>
	/// <param name="client"></param>
	/// <param name="errMsg">错误信息</param>
	/// <param name="msgType">收/发</param>
	internal void WriteErrMsg(TCPClient client, string errMsg, MsgType msgType)
	{
		bool flag = false;
		if (cbMonitorSingleClient.Checked)
		{
			if (cmbClients.SelectedItem != null && (TCPClient)cmbClients.SelectedItem == client)
			{
				flag = true;
			}
		}
		else
		{
			flag = true;
		}
		if (flag)
		{
			txtMsg.AppendText("[" + DateTime.Now.ToString("HH:mm:ss.fff") + "]（" + ((msgType == MsgType.Send) ? "发" : "收") + "）" + client.Name + " => " + errMsg + "\r\n");
		}
	}

	/// <summary>
	/// 清空监控消息
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void tsmiClearMsg_Click(object sender, EventArgs e)
	{
		txtMsg.Clear();
	}

	/// <summary>
	/// 切换监控所有/单个客户端
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void cbMonitorSingleClient_CheckedChanged(object sender, EventArgs e)
	{
	}

	private void SocketServerMonitorForm_Disposed(object sender, EventArgs e)
	{
		BW_SENDDATA.CancelAsync();
	}

	/// <summary>
	/// Clean up any resources being used.
	/// </summary>
	/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
	protected override void Dispose(bool disposing)
	{
		if (disposing && components != null)
		{
			components.Dispose();
		}
		base.Dispose(disposing);
	}

	/// <summary>
	/// Required method for Designer support - do not modify
	/// the contents of this method with the code editor.
	/// </summary>
	private void InitializeComponent()
	{
		this.components = new System.ComponentModel.Container();
		this.groupBox1 = new System.Windows.Forms.GroupBox();
		this.txtMsg = new System.Windows.Forms.TextBox();
		this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
		this.tsmiClearMsg = new System.Windows.Forms.ToolStripMenuItem();
		this.cbMonitorSingleClient = new System.Windows.Forms.CheckBox();
		this.rdShowEncoding = new System.Windows.Forms.RadioButton();
		this.rdShowHex = new System.Windows.Forms.RadioButton();
		this.groupBox2 = new System.Windows.Forms.GroupBox();
		this.rdSendHex = new System.Windows.Forms.RadioButton();
		this.rdSendEncoding = new System.Windows.Forms.RadioButton();
		this.cbSendSingleClient = new System.Windows.Forms.CheckBox();
		this.nudInterval = new System.Windows.Forms.NumericUpDown();
		this.label4 = new System.Windows.Forms.Label();
		this.cbLoop = new System.Windows.Forms.CheckBox();
		this.btnSend = new System.Windows.Forms.Button();
		this.txtSendData = new System.Windows.Forms.TextBox();
		this.label1 = new System.Windows.Forms.Label();
		this.cmbClients = new System.Windows.Forms.ComboBox();
		this.groupBox1.SuspendLayout();
		this.contextMenuStrip.SuspendLayout();
		this.groupBox2.SuspendLayout();
		((System.ComponentModel.ISupportInitialize)this.nudInterval).BeginInit();
		base.SuspendLayout();
		this.groupBox1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
		this.groupBox1.Controls.Add(this.txtMsg);
		this.groupBox1.Controls.Add(this.cbMonitorSingleClient);
		this.groupBox1.Controls.Add(this.rdShowEncoding);
		this.groupBox1.Controls.Add(this.rdShowHex);
		this.groupBox1.Location = new System.Drawing.Point(12, 162);
		this.groupBox1.Name = "groupBox1";
		this.groupBox1.Size = new System.Drawing.Size(760, 287);
		this.groupBox1.TabIndex = 3;
		this.groupBox1.TabStop = false;
		this.txtMsg.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
		this.txtMsg.ContextMenuStrip = this.contextMenuStrip;
		this.txtMsg.Location = new System.Drawing.Point(6, 47);
		this.txtMsg.Multiline = true;
		this.txtMsg.Name = "txtMsg";
		this.txtMsg.ReadOnly = true;
		this.txtMsg.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
		this.txtMsg.Size = new System.Drawing.Size(748, 234);
		this.txtMsg.TabIndex = 3;
		this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[1] { this.tsmiClearMsg });
		this.contextMenuStrip.Name = "contextMenuStrip";
		this.contextMenuStrip.Size = new System.Drawing.Size(101, 26);
		this.tsmiClearMsg.Name = "tsmiClearMsg";
		this.tsmiClearMsg.Size = new System.Drawing.Size(100, 22);
		this.tsmiClearMsg.Text = "清空";
		this.tsmiClearMsg.Click += new System.EventHandler(tsmiClearMsg_Click);
		this.cbMonitorSingleClient.AutoSize = true;
		this.cbMonitorSingleClient.Location = new System.Drawing.Point(139, 26);
		this.cbMonitorSingleClient.Name = "cbMonitorSingleClient";
		this.cbMonitorSingleClient.Size = new System.Drawing.Size(132, 16);
		this.cbMonitorSingleClient.TabIndex = 2;
		this.cbMonitorSingleClient.Text = "仅监控选中的客户端";
		this.cbMonitorSingleClient.UseVisualStyleBackColor = true;
		this.cbMonitorSingleClient.CheckedChanged += new System.EventHandler(cbMonitorSingleClient_CheckedChanged);
		this.rdShowEncoding.AutoSize = true;
		this.rdShowEncoding.Location = new System.Drawing.Point(53, 25);
		this.rdShowEncoding.Name = "rdShowEncoding";
		this.rdShowEncoding.Size = new System.Drawing.Size(71, 16);
		this.rdShowEncoding.TabIndex = 0;
		this.rdShowEncoding.Text = "Encoding";
		this.rdShowEncoding.UseVisualStyleBackColor = true;
		this.rdShowHex.AutoSize = true;
		this.rdShowHex.Checked = true;
		this.rdShowHex.Location = new System.Drawing.Point(6, 25);
		this.rdShowHex.Name = "rdShowHex";
		this.rdShowHex.Size = new System.Drawing.Size(41, 16);
		this.rdShowHex.TabIndex = 1;
		this.rdShowHex.TabStop = true;
		this.rdShowHex.Text = "Hex";
		this.rdShowHex.UseVisualStyleBackColor = true;
		this.groupBox2.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
		this.groupBox2.Controls.Add(this.rdSendHex);
		this.groupBox2.Controls.Add(this.rdSendEncoding);
		this.groupBox2.Controls.Add(this.cbSendSingleClient);
		this.groupBox2.Controls.Add(this.nudInterval);
		this.groupBox2.Controls.Add(this.label4);
		this.groupBox2.Controls.Add(this.cbLoop);
		this.groupBox2.Controls.Add(this.btnSend);
		this.groupBox2.Controls.Add(this.txtSendData);
		this.groupBox2.Location = new System.Drawing.Point(12, 39);
		this.groupBox2.Name = "groupBox2";
		this.groupBox2.Size = new System.Drawing.Size(760, 117);
		this.groupBox2.TabIndex = 2;
		this.groupBox2.TabStop = false;
		this.rdSendHex.AutoSize = true;
		this.rdSendHex.Checked = true;
		this.rdSendHex.Location = new System.Drawing.Point(6, 25);
		this.rdSendHex.Name = "rdSendHex";
		this.rdSendHex.Size = new System.Drawing.Size(41, 16);
		this.rdSendHex.TabIndex = 5;
		this.rdSendHex.TabStop = true;
		this.rdSendHex.Text = "Hex";
		this.rdSendHex.UseVisualStyleBackColor = true;
		this.rdSendHex.CheckedChanged += new System.EventHandler(rdSendHex_CheckedChanged);
		this.rdSendEncoding.AutoSize = true;
		this.rdSendEncoding.Location = new System.Drawing.Point(53, 25);
		this.rdSendEncoding.Name = "rdSendEncoding";
		this.rdSendEncoding.Size = new System.Drawing.Size(71, 16);
		this.rdSendEncoding.TabIndex = 4;
		this.rdSendEncoding.Text = "Encoding";
		this.rdSendEncoding.UseVisualStyleBackColor = true;
		this.rdSendEncoding.CheckedChanged += new System.EventHandler(rdSendEncoding_CheckedChanged);
		this.cbSendSingleClient.AutoSize = true;
		this.cbSendSingleClient.Location = new System.Drawing.Point(139, 26);
		this.cbSendSingleClient.Name = "cbSendSingleClient";
		this.cbSendSingleClient.Size = new System.Drawing.Size(144, 16);
		this.cbSendSingleClient.TabIndex = 4;
		this.cbSendSingleClient.Text = "仅发送给选中的客户端";
		this.cbSendSingleClient.UseVisualStyleBackColor = true;
		this.nudInterval.Increment = new decimal(new int[4] { 100, 0, 0, 0 });
		this.nudInterval.Location = new System.Drawing.Point(182, 75);
		this.nudInterval.Maximum = new decimal(new int[4] { 600000, 0, 0, 0 });
		this.nudInterval.Minimum = new decimal(new int[4] { 100, 0, 0, 0 });
		this.nudInterval.Name = "nudInterval";
		this.nudInterval.Size = new System.Drawing.Size(50, 21);
		this.nudInterval.TabIndex = 8;
		this.nudInterval.Value = new decimal(new int[4] { 1000, 0, 0, 0 });
		this.label4.AutoSize = true;
		this.label4.Location = new System.Drawing.Point(238, 79);
		this.label4.Name = "label4";
		this.label4.Size = new System.Drawing.Size(17, 12);
		this.label4.TabIndex = 9;
		this.label4.Text = "ms";
		this.cbLoop.AutoSize = true;
		this.cbLoop.Location = new System.Drawing.Point(102, 77);
		this.cbLoop.Name = "cbLoop";
		this.cbLoop.Size = new System.Drawing.Size(84, 16);
		this.cbLoop.TabIndex = 7;
		this.cbLoop.Text = "循环频率：";
		this.cbLoop.UseVisualStyleBackColor = true;
		this.cbLoop.CheckedChanged += new System.EventHandler(cbLoop_CheckedChanged);
		this.btnSend.Location = new System.Drawing.Point(6, 74);
		this.btnSend.Name = "btnSend";
		this.btnSend.Size = new System.Drawing.Size(90, 23);
		this.btnSend.TabIndex = 6;
		this.btnSend.Text = "发送(&S)";
		this.btnSend.UseVisualStyleBackColor = true;
		this.btnSend.Click += new System.EventHandler(btnSend_Click);
		this.txtSendData.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
		this.txtSendData.Location = new System.Drawing.Point(6, 47);
		this.txtSendData.Name = "txtSendData";
		this.txtSendData.Size = new System.Drawing.Size(748, 21);
		this.txtSendData.TabIndex = 3;
		this.label1.AutoSize = true;
		this.label1.Location = new System.Drawing.Point(20, 16);
		this.label1.Name = "label1";
		this.label1.Size = new System.Drawing.Size(77, 12);
		this.label1.TabIndex = 0;
		this.label1.Text = "客户端列表：";
		this.cmbClients.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
		this.cmbClients.FormattingEnabled = true;
		this.cmbClients.Location = new System.Drawing.Point(103, 13);
		this.cmbClients.Name = "cmbClients";
		this.cmbClients.Size = new System.Drawing.Size(121, 20);
		this.cmbClients.TabIndex = 1;
		base.AutoScaleDimensions = new System.Drawing.SizeF(6f, 12f);
		base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
		base.ClientSize = new System.Drawing.Size(784, 461);
		base.Controls.Add(this.cmbClients);
		base.Controls.Add(this.label1);
		base.Controls.Add(this.groupBox2);
		base.Controls.Add(this.groupBox1);
		this.MinimumSize = new System.Drawing.Size(500, 350);
		base.Name = "SocketServerMonitorForm";
		this.Text = "Socket服务监控";
		base.Load += new System.EventHandler(SocketServerMonitorForm_Load);
		this.groupBox1.ResumeLayout(false);
		this.groupBox1.PerformLayout();
		this.contextMenuStrip.ResumeLayout(false);
		this.groupBox2.ResumeLayout(false);
		this.groupBox2.PerformLayout();
		((System.ComponentModel.ISupportInitialize)this.nudInterval).EndInit();
		base.ResumeLayout(false);
		base.PerformLayout();
	}
}
